#!/usr/bin/perl -w
use strict;
$| = 1;

#       Redistribution and use in source and binary forms, with or without
#       modification, are permitted provided that the following conditions are
#       met:
#       
#       * Redistributions of source code must retain the above copyright
#         notice, this list of conditions and the following disclaimer.
#       * Redistributions in binary form must reproduce the above
#         copyright notice, this list of conditions and the following disclaimer
#         in the documentation and/or other materials provided with the
#         distribution.
#       * Neither the name of the  nor the names of its
#         contributors may be used to endorse or promote products derived from
#         this software without specific prior written permission.
#       
#       THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
#       "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
#       LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
#       A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
#       OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
#       SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
#       LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
#       DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
#       THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
#       (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
#       OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#	Copyright (C) 2008-2011 Aleksandr Deviatkin aka alid

#
# Корректировка часов счетчика Меркурий-203.2Т
# 2009-03-25 alid
# 2011-08-02 alid
#

use lib "$ENV{MY}/counter";
use Mercury;

my (@args, %opts);
foreach(@ARGV){
   if(/^\-(\S)(.*)/){	$opts{$1} = $2;	} else {	push @args, $_;	}
}
my ($saddr, $device, $flag) = (@args);
die "Usage: $0 addr serial-dev"	unless(defined $saddr && $device);

my $verb = exists $opts{v};
my $adj = exists $opts{a};
my $retries = (exists $opts{r}) ? $opts{r} : 10;

my $addr = sprintf("%08x",$saddr);
$addr =~ s/(\w\w)(\w\w)(\w\w)(\w\w)/$1 $2 $3 $4/;
print "Addr: [$addr]\n"	if $verb;

my $STALL_DEFAULT=2;	# how many seconds to wait for new input
my $MAXLENGTH = 255;	# наибольшая длина пакета

my ($status,$cnt,@data);
my $connect = Mercury->new($device,'M203',$addr,'','',$retries,$verb);

if($verb) {
	print "Connection testing ... "	if $verb;
	$status = $connect->tst();
	print "$status\n"	if $verb;
	die	"[$addr] Connection failed: [$status]"	unless($status=~/ok/);
}

my ($ss,$mm,$hh,$md,$mon,$ye,$wd) = (localtime(time()))[0,1,2,3,4,5,6];
$ye += 1900;
$mon++;
($ss,$mm,$hh,$mon,$md,$wd) = map {sprintf("%02d",$_)} ($ss,$mm,$hh,$mon,$md,$wd);

# get time from device
if($verb || !$adj) {
	($status,$cnt,@data) = $connect->get('21');
	die "[$addr] 21h request failed: [$status]"	unless($status=~/ok/);
	print "[$status][$cnt][".join(' ',@data)."]\n"	if $verb;
	my ($year,$mons,$mday,$hour,$min,$sec,$dow) = ("20".$data[11],$data[10],$data[9],$data[6],$data[7],$data[8],$data[5]);
	($status,$cnt,@data) = $connect->get('24');
	die "[$addr] 24h request failed: [$status]"	unless($status=~/ok/);
	print "[$status][$cnt][".join(' ',@data)."]\n"	if $verb;
	print "[$saddr][x$addr] $year-$mons-$mday $hour:$min:$sec [".(($data[5] eq '00')? 'none':'auto')."] weekday: $dow\n";
}
if($adj) {
	print "Time-date correction: $wd $ye-$mon-$md $hh:$mm:$ss\n"	if($verb);
	my $cmd = '02';
	my $Y;
	if($ye =~ /(\d\d)$/) { $Y = $1; }
	($status,$cnt,@data) = $connect->get("$cmd $wd $hh $mm $ss $md $mon $Y");
	die "[$addr] 02h request failed: [$status]"	unless($status=~/ok/);
	print "[$status][$cnt][".join(' ',@data)."]\n"	if $verb;
	die "[$addr] 02h time correction failed: [$status][$cnt][".join(' ',@data)."]"	unless($data[4] eq $cmd);
}
if(defined $flag) {
	$flag = sprintf("%02X", $flag);	# автоматический переход на летнее время
	my $cmd = '05';
	($status,$cnt,@data) = $connect->get("$cmd $flag");
	die "[$addr] 02h request failed: [$status]"	unless($status=~/ok/);
	print "[$status][$cnt][".join(' ',@data)."]\n"	if $verb;
	die "[$addr] 05h time flag failed: [$status][$cnt][".join(' ',@data)."]"	unless($data[4] eq $cmd);
}


$connect->quit();

